package com.itheima.controller;

import com.itheima.common.Code;
import com.itheima.common.MessageConstant;
import com.itheima.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
 * @Author: zhuan
 * @Desc: 文件上传下架-公共控制器
 * @Date: 2022-05-18 15:47:53
 */
@Slf4j
@RestController
@RequestMapping("/common")
public class CommonController {

		@Value("${file.uploadPath}")
		private String filePath;

		/**
		 * 功能描述: 文件上传代码
		 * @param file
		 * @param request
		 * @param response
		 * @return : com.itheima.common.Result
		 */
		@PostMapping("/upload")
		public Result upload(MultipartFile file, HttpServletRequest request, HttpServletResponse response){
				// 文件保存目录路径
				/*String savePath = request.getSession().getServletContext().getRealPath("/") + "upload\\image" + File.separatorChar
																	+ File.separatorChar;*/
				/*String saveUrl = request.getContextPath()+ File.separatorChar + "upload/image" + File.separatorChar
																 + File.separatorChar;*/
				// 定义允许上传的文件扩展名
				HashMap<String, String> extMap = new HashMap<String, String>();
				extMap.put("image", "gif,jpg,jpeg,png,bmp");
				// 最大文件大小
				long maxSize = 1000000;
				response.setContentType("text/html; charset=UTF-8");
				String error ="";
				if (!ServletFileUpload.isMultipartContent(request)) {
						return new Result(Code.ERROR, MessageConstant.FILE_NOT_SELECTED);
				}
				File uploadDir = new File(filePath);
				// 判断文件夹是否存在,如果不存在则创建文件夹
				if (!uploadDir.exists()) {
						uploadDir.mkdirs();
				}
				// 检查目录写权限
				if (!uploadDir.canWrite()) {
						return new Result(Code.ERROR, MessageConstant.DIR_HAVA_NO_WRITER_PERMISSION);
				}
				String dirName = request.getParameter("dir");
				if (dirName == null) {
						dirName = "image";
				}
				if (!extMap.containsKey(dirName)) {
						return new Result(Code.ERROR, MessageConstant.DIR_IS_INCORRECT);
				}
				MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
				Map<String, MultipartFile> fileMap = mRequest.getFileMap();
				String fileName = null;
				for (Iterator<Map.Entry<String, MultipartFile>> it = fileMap.entrySet().iterator(); it.hasNext();) {
						Map.Entry<String, MultipartFile> entry = it.next();
						MultipartFile mFile = entry.getValue();
						fileName = mFile.getOriginalFilename();
						// 检查文件大小
						if (mFile.getSize() > maxSize) {
								return new Result(Code.ERROR, MessageConstant.FILE_SIZE_EXCEEDS_LIMIT);
						}
						// 检查文件是否有操作权限
						String fileExt = fileName.substring(fileName.lastIndexOf(".")+1);
						if (!Arrays.<String> asList(extMap.get(dirName).split(",")).contains(fileExt)) {
								return new Result(Code.ERROR, MessageConstant.FILE_EXT_IS_NOT_ALLOWED);
						}
						UUID uuid = UUID.randomUUID();
						//生成文件名称
						fileName = uuid.toString()+"."+ fileExt;
						//生成文件最终保存的磁盘的路径
						String path = filePath + uuid.toString() +"."+ fileExt;
						try {
								//定义磁盘输出流
								BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(path));
								FileCopyUtils.copy(mFile.getInputStream(), outputStream);
						} catch (IOException e) {
								e.printStackTrace();
						}
				}
				return new Result(Code.OK,MessageConstant.FILE_UPLOAD_SUCCESS,fileName);
		}
		/**
		 * 文件下载
		 * @param name
		 * @param response
		 */
		@GetMapping("/download")
		public void download(String name, HttpServletResponse response){
				FileInputStream fileInputStream = null;
				ServletOutputStream outputStream = null;
				try {
						//输入流，通过输入流读取文件内容
						File file = new File(filePath + name);
						if(!file.exists()){
								return;
						}
						fileInputStream = new FileInputStream(file);
					System.out.println(file);
						//输出流，通过输出流将文件写回浏览器
						outputStream = response.getOutputStream();
						response.setContentType("image/jpeg");
						int len = 0;
						byte[] bytes = new byte[1024];
						//输入流数据转到输出流中
						while ((len = fileInputStream.read(bytes)) != -1){
								outputStream.write(bytes,0,len);
								//输出流中数据刷到浏览器
								outputStream.flush();
						}
				} catch (Exception e) {
						e.printStackTrace();
				}finally {
						//关闭资源
						try {
								outputStream.close();
								fileInputStream.close();
						} catch (IOException e) {
								log.error("文件下载，资源关闭异常：{}",e.getMessage());
						}

				}
		}
}
